﻿#region Copyright Info

// 
// Majesty of Omega - The next evolution of macro management space strategy
// 
// Copyright 2007-2009 André Claaßen
// 
// This file is protected by the terms and conditions of the
// Microsoft Community License (Ms-CL 1.1), a copy of which should
// have been distributed along with this software. If not,
// you may find the license information at the following URL:
// 
// http://www.microsoft.com/resources/sharedsource/licensingbasics/communitylicense.mspx

#endregion

#region

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Windows.Documents;
using System.Windows.Media;
using DesignByContract;

#endregion

namespace Majesty_of_Omega.GUI.Utility
{
    /// <summary>
    /// This class converts a Moo Text String with simple formattings to FlowDocument inlines
    /// </summary>
    public class MooTextToInlineConverter
    {
        /// <summary>
        /// regular expressions for the various patterns
        /// </summary>
        private const string pattern = 
                @"(?<link>http://[\w\.?=%&=\-@/$,]*)|(?<linebreak>/p\s*)|" + 
                @"(?<linebreak>/p\s*)";

        /// <summary>
        /// Converts the moo text to inlines.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public List<Inline> ConvertMooTextToInlines(string text)
        {
            List<Inline> inlines = new List<Inline>();
            if (text == null)
                return inlines;


            int iPreviousPosition = 0;
            Regex regexPattern = new Regex(pattern, RegexOptions.Singleline);
            string parseString = text.Trim();

            Match match = regexPattern.Match(parseString);
            while (match.Success)
            {
                int iGroupNumber = 0;
                foreach (Group group in match.Groups)
                {
                    if (group.Success && iGroupNumber > 0)
                    {
                        string groupname = regexPattern.GroupNameFromNumber(iGroupNumber);
                        AddPlainText(inlines, parseString, iPreviousPosition, group.Index);
                        inlines.Add(ResolveToken(groupname, group.Value));
                        iPreviousPosition = group.Index + group.Length;
                    }
                    iGroupNumber++;
                }
                match = match.NextMatch();
            }
            AddPlainText(inlines, parseString, iPreviousPosition, parseString.Length);
            return inlines;
        }

        /// <summary>
        /// Adds a plain text to the document inlines
        /// </summary>
        /// <param name="inlines">The inlines.</param>
        /// <param name="text">The text.</param>
        /// <param name="startPosition">The start position.</param>
        /// <param name="endPosition">The end position.</param>
        private static void AddPlainText(ICollection<Inline> inlines, string text, int startPosition, int endPosition)
        {
            Require.IsTrue(startPosition<=endPosition);
            if (startPosition < endPosition)
                inlines.Add(new Run(text.Substring(startPosition, endPosition - startPosition)));
        }

        /// <summary>
        /// Resolves the token in the moo rich text and creates a corresponding inline
        /// </summary>
        /// <example>
        /// <![CDATA[
        ///     A new line\p and a further new line\p
        /// ]]>
        /// </example>
        /// <param name="groupname">The groupname.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        private static Inline ResolveToken(string groupname, string value)
        {
            Inline result = null;
            switch (groupname)
            {
                case "linebreak":
                    result = new LineBreak();
                    break;
                case "link":
                    result = new Hyperlink (new Run(value))
                                 {
                                     NavigateUri = new Uri(value),
                                     Foreground = Brushes.Azure
                                 };
                    break;
                default:
                    Require.ThrowException("Error in converting Moo text to inlines. the groupname " + groupname +
                                           "is not legal.");
                    break;
            }
            return result;
        }
    }
}